import { validate } from 'class-validator';
/*
 * @Author: Jimmy
 * @LastModifiedBy: Jimmy
 * @Date: 2024-05-25 20:01:22
 * @LastEditTime: 2024-09-04 21:43:33
 * @FilePath: /nest_study/server/src/modules/system/access/access.service.ts
 */
import { Inject, Injectable } from '@nestjs/common';
import { ClientInfoDto, LoginDto } from './dto/index.dto';
import { UserService } from '../user/user.service';
import { AxiosService } from 'src/modules/axios/axios.service';
import { ResultData, SUCCESS_CODE } from 'src/common/utils/result';
import { SYS_STATUS } from 'src/common/enum/status';
import { SystemUserEntity } from '../user/entities/user.entity';
import { SYS_USER_TYPE } from 'src/common/enum/user';
import { SystemRoleEntity } from '../role/entities/role.entity';
import { SystemPostEntity } from '../post/entities/post.entity';
import { SystemDeptEntity } from '../dept/entities/dept.entity';
import { SystemMenuEntity } from '../menu/entities/menu.entity';
import { EntityManager } from 'typeorm';
import { getNowDate } from 'src/common/utils';
import { CacheEnum } from 'src/common/enum/cache';
import { RedisService } from 'src/modules/redis/redis.service';
import { LoginLogService } from 'src/modules/monitor/login-log/login-log.service';
import { CacheService } from 'src/modules/cache/cache.service';

@Injectable()
export class AccessService {
  constructor(
    private readonly entityManager: EntityManager,
    @Inject(UserService)
    private readonly userService: UserService,
    @Inject(AxiosService)
    private readonly axiosService: AxiosService,
    private readonly redisService: RedisService,
    private readonly loginlogService: LoginLogService,
    private readonly cacheService: CacheService,
  ) {
  }

  /**
   * 登录
   * @param user 
   * @param clientInfo 
   */
  async login(user: LoginDto, clientInfo: ClientInfoDto) {
    const loginLog = {
      ...clientInfo,
      userName: user.username,
      status: '0',
      msg: '',
    }
    try {
      let res = await this.axiosService.getIpAddress(clientInfo.ip);
      loginLog.location = res.addr;
      loginLog.ip = res.ip;
    } catch (err) { }
    const result = await this.userService.login(user, loginLog);
    loginLog.status = result.code === SUCCESS_CODE ? '0' : '1';
    loginLog.msg = result.msg;
    this.loginlogService.create(loginLog);
    return result;
  }
  /**
   * 退出登录
   * @param clientInfo 
   */
  async logout(clientInfo: ClientInfoDto, user: any) {
    const logoutLog = {
      ...clientInfo,
      userName: user.username,
      status: SYS_STATUS.COMMON,
      msg: '退出成功'
    }
    try {
      let res = await this.axiosService.getIpAddress(clientInfo.ip);
      logoutLog.ip = res.ip;
      logoutLog.location = res.addr;
      let { token } = user;
      this.redisService.del(`${CacheEnum.LOGIN_TOKEN_KEY}${token}`);
      this.cacheService.storeDel(`user_${user.id}_token`)
      this.redisService.del(`user_${user.id}_token`);
    } catch (err) { }
    this.loginlogService.create(logoutLog);
    return ResultData.ok();
  }
  /**
   * 生成种子数据
   */
  async initData() {
    try {
      //系统基本菜单
      const home = new SystemMenuEntity();
      home.name = '首页';
      home.path = '/dashboard/index';
      home.sort = 1;
      home.menuType = "M";
      home.parentId = -1;
      home.external = '1';
      home.visible = '1';
      home.icon = 'menu/dashboard';
      const system = new SystemMenuEntity();
      system.name = '系统管理';
      system.path = '/system';
      system.sort = 99;
      system.menuType = "C";
      system.parentId = -1;
      system.external = '1';
      system.visible = '1';
      system.icon = 'menu/system';
      const monitor = new SystemMenuEntity();
      monitor.name = '监控管理';
      monitor.path = '/monitor';
      monitor.sort = 100;
      monitor.menuType = "C";
      monitor.parentId = -1;
      monitor.external = '1';
      monitor.visible = '1';
      monitor.icon = 'menu/monitor';
      let siteMenuList = await this.entityManager.save(SystemMenuEntity, [
        home,
        system,
        monitor
      ]);
      //系统管理菜单的id
      let systemMenuId = siteMenuList[1].id;
      const userMenu = new SystemMenuEntity();
      userMenu.name = '用户管理';
      userMenu.path = '/system/user/index';
      userMenu.sort = 1;
      userMenu.menuType = "M";
      userMenu.parentId = systemMenuId;
      userMenu.external = '1';
      userMenu.visible = '1';
      userMenu.icon = 'menu/user';
      const roleMenu = new SystemMenuEntity();
      roleMenu.name = '角色管理';
      roleMenu.path = '/system/role/index';
      roleMenu.sort = 2;
      roleMenu.menuType = "M";
      roleMenu.parentId = systemMenuId;
      roleMenu.external = '1';
      roleMenu.visible = '1';
      roleMenu.icon = 'menu/role';
      const postMenu = new SystemMenuEntity();
      postMenu.name = '岗位管理';
      postMenu.path = '/system/post/index';
      postMenu.sort = 3;
      postMenu.menuType = "M";
      postMenu.parentId = systemMenuId;
      postMenu.external = '1';
      postMenu.visible = '1';
      postMenu.icon = 'menu/position';
      const deptMenu = new SystemMenuEntity();
      deptMenu.name = '部门管理';
      deptMenu.path = '/system/dept/index';
      deptMenu.sort = 3;
      deptMenu.menuType = "M";
      deptMenu.parentId = systemMenuId;
      deptMenu.external = '1';
      deptMenu.visible = '1';
      deptMenu.icon = 'menu/dept';

      const dictMenu = new SystemMenuEntity();
      dictMenu.name = '字典管理';
      dictMenu.path = '/system/dict/index';
      dictMenu.sort = 4;
      dictMenu.menuType = "M";
      dictMenu.parentId = systemMenuId;
      dictMenu.external = '1';
      dictMenu.visible = '1';
      dictMenu.icon = 'common/international';

      const menu = new SystemMenuEntity();
      menu.name = '菜单管理';
      menu.path = '/system/menu/index';
      menu.sort = 9;
      menu.menuType = "M";
      menu.parentId = systemMenuId;
      menu.external = '1';
      menu.visible = '1';
      menu.icon = 'menu/menu';
      let systemMenuList = await this.entityManager.save(SystemMenuEntity, [
        userMenu,
        roleMenu,
        postMenu,
        deptMenu,
        dictMenu,
        menu
      ]);
      const dictDataMenu = new SystemMenuEntity();
      dictDataMenu.name = '字典数据';
      dictDataMenu.path = '/system/dict/data/index';
      dictDataMenu.sort = 1;
      dictDataMenu.menuType = "M";
      dictDataMenu.parentId = systemMenuList[4].id;
      dictDataMenu.external = '1';
      dictDataMenu.visible = '0';
      dictDataMenu.icon = 'common/international';
      let systemDictData = await this.entityManager.save(SystemMenuEntity, [
        dictDataMenu
      ]);
      //监控管理菜单的id
      let monitorenuId = siteMenuList[2].id;
      const onlineMenu = new SystemMenuEntity();
      onlineMenu.name = '在线监控';
      onlineMenu.path = '/monitor/online/index';
      onlineMenu.sort = 1;
      onlineMenu.menuType = "M";
      onlineMenu.parentId = monitorenuId;
      onlineMenu.external = '1';
      onlineMenu.visible = '1';
      onlineMenu.icon = 'menu/role';
      const loginlogMenu = new SystemMenuEntity();
      loginlogMenu.name = '登录监控';
      loginlogMenu.path = '/monitor/login_log/index';
      loginlogMenu.sort = 2;
      loginlogMenu.menuType = "M";
      loginlogMenu.parentId = monitorenuId;
      loginlogMenu.external = '1';
      loginlogMenu.visible = '1';
      loginlogMenu.icon = 'area';
      let monitorMenuList = await this.entityManager.save(SystemMenuEntity, [
        onlineMenu,
        loginlogMenu,
        menu
      ]);

      const user = new SystemUserEntity();
      user.userName = 'admin';
      user.nickName = '超级管理员';
      user.password = '$2a$10$Qsg8/lnYn.BtVAkeSbEZ.ek.JEeJiyZ22U.rYeRl1HweRor/9wo/S';
      user.phone = '13245678910';
      user.loginTime = getNowDate();
      user.userType = SYS_USER_TYPE.SYS;

      const role = new SystemRoleEntity();
      role.name = '超级管理员';
      role.code = 'super';
      role.sort = 0;
      role.menus = [
        home,
        system,
        monitor,
        userMenu,
        roleMenu,
        postMenu,
        deptMenu,
        dictMenu,
        dictDataMenu,
        menu,
        onlineMenu,
        loginlogMenu
      ];
      role.menuIds = [
        siteMenuList[0].id,
        siteMenuList[1].id,
        siteMenuList[2].id,
        systemMenuList[0].id,
        systemMenuList[1].id,
        systemMenuList[2].id,
        systemMenuList[3].id,
        systemMenuList[4].id,
        systemDictData[0].id,
        systemMenuList[5].id,
        monitorMenuList[0].id,
        monitorMenuList[1].id,
      ]

      const post = new SystemPostEntity();
      post.name = '超管';
      post.code = 'super';
      post.sort = 0;
      const dept = new SystemDeptEntity();
      dept.name = '总经办'
      dept.leader = 'admin'
      dept.phone = '13212345678'
      dept.parentId = -1;

      let roleInfo = await this.entityManager.save(SystemRoleEntity, role);
      let postInfo = await this.entityManager.save(SystemPostEntity, post);
      let deptInfo = await this.entityManager.save(SystemDeptEntity, dept);
      user.postIds = [postInfo.id];
      user.roleIds = [roleInfo.id];
      user.deptIds = [deptInfo.id];

      await this.entityManager.save(SystemUserEntity, [user]);
      return ResultData.ok();
    } catch (err) {
      return ResultData.fail(500, '初始化数据失败');
    }
  }

}
